package com.macro.mall.config;

import com.macro.mall.service.UmsAdminService;
import com.macro.mall.service.UmsResourceService;
import com.macro.model.UmsResource;
import com.macro.mall.component.DynamicSecurityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)  //开启基于方法的安全认证机制，也就是说在web层的controller启用注解机制的安全确认，
public class MallSecurityConfig extends SecurityConfig {

    @Autowired
    private UmsAdminService adminService;

    @Autowired
    private UmsResourceService resourceService;

    @Bean
    public UserDetailsService userDetailsService(){
        //用一个匿名内部类实现了 UserDetailsService
       return username -> adminService.loadUserByUsername(username);

        /* 等价于

        return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                return adminService.loadUserByUsername(username);
            }
        };

         */
    }

    @Bean
    public DynamicSecurityService dynamicSecurityService(){
        return new DynamicSecurityService() {
            @Override
            public Map<String, ConfigAttribute> loadDataSource() {
                Map<String,ConfigAttribute> map = new ConcurrentHashMap<>();
                List<UmsResource> resources = resourceService.listAll();
                for(UmsResource resource : resources)
                    map.put(resource.getUrl(),new org.springframework.security.access.SecurityConfig(resource.getId() + ":" + resource.getName()));
                return map;
            }
        };
    }

}
